﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace LINQToolKit
{
    public sealed class EntityQuery<T> : IQueryable<T>, IOrderedQueryable<T>
    {
        private Expression _expression;
        private IQueryProvider _provider;

        public EntityQuery(IQueryProvider provider)
        {
            provider.AssertNull("provider");
            this._provider = provider;
        }

        public EntityQuery(IQueryProvider provider, Expression expression)
            : this(provider)
        {
            expression.AssertNull("expression");
            this._expression = expression;
        }

        public IEnumerator<T> GetEnumerator()
        {
            var result = this.Provider.Execute(this.Expression);

            if (result == null)
            {
                return new List<T>().GetEnumerator();
            }
            else
            {
                return ((IEnumerable<T>)result).GetEnumerator();
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public Type ElementType
        {
            get { return typeof(T); }
        }

        public Expression Expression
        {
            get 
            {
                if (this._expression == null)
                {
                    this._expression = Expression.Constant(this);
                }

                return this._expression;
            }
        }

        public IQueryProvider Provider
        {
            get { return this._provider; }
        }
    }
}
